<?php

namespace app\company\service;

use app\company\model\CompanyDepartmentModel;
use app\exception\MsgException;
use think\db\exception\DbException;

class DepartmentService extends Base
{

    /**
     * 获取表格数据
     * @param array $params
     * @return array
     */
    public function getList(array $params): array
    {
        $model = new CompanyDepartmentModel();

        $condition = [];
        if(!empty($params['cid'])){
            $condition[] = ['cid', '=', $params['cid']];
        }
        if(!empty($params['keyword'])) {
            $condition[] = ['name', 'like', "%{$params['keyword']}%"];
        }

        $list = $model->where($condition)
            ->column('*','id');

        return self::recursionDept($list, 0);
    }

    /**
     * 递归数组
     * @param $arr
     * @param $pid
     * @return array
     */
    public static function recursionDept(&$arr, $pid): array
    {
        $data = [];
        foreach($arr as $id => $value){
            if($value['pid'] == $pid){
                $children = self::recursionDept($arr, $id);
                if(count($children)){
                    $value['children'] = $children;
                }
                $data[] = $value;
            }
        }
        return $data;
    }

    /**
     * 新增
     * @param array $data
     * @return CompanyDepartmentModel
     * @throws DbException|MsgException
     */
    public function add(array $data): CompanyDepartmentModel
    {
        //检查是否已存在该部门
        $isExist = CompanyDepartmentModel::where([
            ['cid', '=', $data['cid']],
            ['name', '=', $data['name']],
        ])->find();
        if($isExist) throw new MsgException("该部门已存在");

        $data['level'] = 1;
        if($data['pid'] > 0){
            $pL = CompanyDepartmentModel::where('id', $data['pid'])->value('level');
            if($pL === null) throw new MsgException("上级部门不存在");
            $data['level'] = $pL + 1;
        }

        $model = CompanyDepartmentModel::create($data);

        self::updateDeptTreeIds($model);
        return $model;
    }

    /**
     * 编辑
     * @param array $data
     * @return CompanyDepartmentModel
     * @throws DbException|MsgException
     */
    public function edit(array $data): CompanyDepartmentModel
    {
        if($data['pid'] > 0){
            $pL = CompanyDepartmentModel::where('id', $data['pid'])->value('level');
            if($pL === null) throw new MsgException("上级部门不存在");
            $data['level'] = $pL + 1;
        }

        $model = CompanyDepartmentModel::find($data['id']);
        $model->save($data);

        self::updateDeptTreeIds($model);

        return $model;
    }

    /**
     * 批量删除
     * @param $ids
     * @param $isRecycle bool 是否强制删除
     * @return bool
     * @throws DbException
     */
    public function delete($ids, bool $isRecycle = false): bool
    {
        if(!is_array($ids)) $ids = [$ids];

        foreach ($ids as $id){
            $dept = CompanyDepartmentModel::find($id);
            $dept->destroy($id, $isRecycle);

            //查询上级 -更新部门树
            $pDept = CompanyDepartmentModel::find($dept->pid);
            self::updateDeptTreeIds($pDept);
        }
        return true;
    }

    /**
     * 还原回收站
     * @param $id
     * @return bool
     * @throws DbException
     */
    public function reduction($id): bool
    {
        return CompanyDepartmentModel::onlyTrashed()
            ->find($id)
            ->restore();
    }

    /**
     * 更新子部门ID -自动向上递归
     * @param CompanyDepartmentModel $model
     * @param bool $isRecursive 是否向上递归
     * @throws DbException
     */
    public static function updateDeptTreeIds(CompanyDepartmentModel $model, bool $isRecursive = true): void
    {
        $dept = CompanyDepartmentModel::where('id', $model->id)
            ->field('id,pid')
            ->find();

        $ids = self::makeDeptIds($model->cid, $model->id, false);
        $dept->where('id', $model->id)->update([
            'tree' => implode(',', $ids)
        ]);

        //递归上级
        if($isRecursive and $dept->pid > 0){
            $pModel = CompanyDepartmentModel::find($dept->pid);
            self::updateDeptTreeIds($pModel);
        }
    }

    /**
     * 从数据库生成部门树ID
     * @param int $cid 公司ID
     * @param int $id 部门ID
     * @param bool $itself 是否包含查询id本身
     * @return array|int[]
     */
    public static function makeDeptIds(int $cid, int $id, bool $itself = true): array
    {
        $arr = $id == 0 ? [] : ($itself? [$id] : []);
        $ids = CompanyDepartmentModel::where('pid', $id)
            ->where('cid', $cid)
            ->column('id');
        if($ids){
            foreach($ids as $v){
                $arr[] = $v;
                $_ids = self::getDeptIds($v, false);
                if($_ids){
                    $arr = array_merge($arr, $_ids);
                }
            }
        }
        return $arr;
    }

    /**
     * 获取部门预设的子部门id
     * @param int $id 查询部门ID
     * @param bool $useThis 是否包含查询id本身
     * @return array
     */
    public static function getDeptIds(int $id, bool $useThis = true): array
    {
        $arr = [];
        if($id != 0){
            //取预设的缓存树
            $tree = CompanyDepartmentModel::where('id', $id)->value('tree');
            if($tree){
                $arr = array_merge($arr, explode(',', $tree));
            }
        }
        //追加本身
        if($useThis) $arr[] = $id;
        return $arr;
    }

}